package com.cn.serverline.lineicp.produce.service.impl;

import cn.hutool.core.date.DateTime;
import com.cn.serverline.lineicp.produce.entity.StepRequired;
import com.cn.serverline.lineicp.produce.entity.dto.PlanDetailsDTO;
import com.cn.serverline.lineicp.produce.entity.dto.PlanRequestDTO;
import com.cn.serverline.lineicp.produce.entity.vo.PlanDetailsVO;
import com.cn.serverline.lineicp.produce.entity.vo.PlanDetailsbVO;
import com.cn.serverline.lineicp.produce.entity.vo.StopDurationInfoVo;
import com.cn.serverline.lineicp.produce.entity.vo.TasksByLotNoVo;
import com.cn.serverline.lineicp.produce.mapper.StepRequiredMapper;
import com.cn.serverline.lineicp.produce.service.IStepRequiredService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 工步所需 服务实现类
 * </p>
 *
 * @author 王烁
 * @since 2024-08-12
 */
@Service
public class TeStepRequiredServiceImpl extends MPJBaseServiceImpl<StepRequiredMapper, StepRequired> implements IStepRequiredService {

    @Autowired
    private StepRequiredMapper stepRequiredMapper;

    /**
     * 获取生产执行追溯页 第一个列表数据
     *
     * @param lotNo
     * @return
     */
    @Override
    public List<TasksByLotNoVo> getTasksByLotNo(String lotNo) {
        return stepRequiredMapper.findByLotNo(lotNo);
    }


    /**
     * 获取生产执行追溯页 第二个列表数据
     *
     * @param lotNo
     * @return
     */
    @Override
    public List<StopDurationInfoVo> getStopDurationInfo(String lotNo) {
        // 获取合并的停工时间信息
        List<StopDurationInfoVo> stopDurationInfoVos = getCombinedStopDurationInfo(lotNo);

        // 按结束时间排序
        List<StopDurationInfoVo> sortedList = stopDurationInfoVos.stream().filter(list -> !list.getCtpmID().equals(null)) // 仅保留非空集合
                .sorted(Comparator.comparing(stopDurationInfoVo -> stopDurationInfoVo.getFirstEndTime().getTime()))
                .collect(Collectors.toList());
        for (int i = 0; i < sortedList.size() / 2; i++) {
            // 计算第一条和第二条之间的间隔时间
            if (sortedList.size() >= 2) {
                StopDurationInfoVo first = sortedList.get(0);
                StopDurationInfoVo second = sortedList.get(1);
                return calculateDuration(first, second);
            }
        }
        return sortedList;
    }


    /**
     * 获取生产执行追溯页 总装的叫料、下发id、工序id和名称的查询
     *
     * @param requestDTO
     * @return
     */
    @Override
    public List<HashMap<String, String>> getPlanDetails(PlanRequestDTO requestDTO) {
        List<PlanDetailsVO> planDetails = stepRequiredMapper.getPlanDetails(requestDTO);

        // 按叫料次数分组
        Map<String, List<PlanDetailsVO>> collect = planDetails.stream()
                .collect(Collectors.groupingBy(PlanDetailsVO::getCallMaterialNumber));

        // 使用 LinkedHashMap 保证插入顺序
        Map<String, HashMap<String, String>> mergedData = new LinkedHashMap<>();

        // 遍历每一个叫料次数对应的 PlanDetailsVO 列表
        for (Map.Entry<String, List<PlanDetailsVO>> entry : collect.entrySet()) {
            String callMaterialNumber = entry.getKey();
            List<PlanDetailsVO> detailsList = entry.getValue();

            // 处理每个 PlanDetailsVO 对象
            detailsList.stream()
                    .filter(planDetailsVO ->
                            Objects.nonNull(planDetailsVO.getProcProcessId()) &&
                                    Objects.nonNull(planDetailsVO.getSmallBatchNumber()) &&
                                    Objects.nonNull(planDetailsVO.getPartNumber()))
                    .forEach(planDetailsVO -> {
                        // 构造唯一键
                        String key = callMaterialNumber + "_" + planDetailsVO.getSmallBatchNumber() + "_" + planDetailsVO.getPartNumber();

                        // 检查唯一键和工序ID是否为null
                        if (Objects.nonNull(key)  && Objects.nonNull(planDetailsVO.getProcProcessId())) {
                            // 如果该键已经存在，跳过新的放入操作
                            HashMap<String, String> existingMap = mergedData.get(key);
                            if (existingMap == null) {
                                existingMap = new HashMap<>();
                                existingMap.put("叫料:", callMaterialNumber);
                                existingMap.put("小批次号:", planDetailsVO.getSmallBatchNumber());
                                existingMap.put("件号:", planDetailsVO.getPartNumber());
                                existingMap.put(planDetailsVO.getProcProcessId(), planDetailsVO.getProcessName());
                                mergedData.put(key, existingMap);
                            } else {
                                // 如果有新的工序信息，则合并到现有的 HashMap 中
                                existingMap.put(planDetailsVO.getProcProcessId(), planDetailsVO.getProcessName());
                            }
                        }
                    });
        }
        // 返回合并后的结果
        return new ArrayList<>(mergedData.values());
    }




    /**
     * 获取生产执行追溯页 部装的叫料、下发id、工序id和名称的查询
     *
     * @param requestDTO
     * @return
     */
    @Override
    public Map<String, List<PlanDetailsbVO>> getProductionTraceabilityDetails(PlanDetailsDTO requestDTO) {
        List<PlanDetailsbVO> productionTraceabilityDetails = stepRequiredMapper.getProductionTraceabilityDetails(requestDTO);
        //进行分组
        Map<String, List<PlanDetailsbVO>> collect = productionTraceabilityDetails.stream().collect(Collectors.groupingBy(PlanDetailsbVO::getCallMaterialNumber));
        return collect;
    }

    /**
     * 获取合并后的部装和总装数据
     *
     * @param lotNo
     * @return
     */
    private List<StopDurationInfoVo> getCombinedStopDurationInfo(String lotNo) {
        List<StopDurationInfoVo> stopDurationInfoVos = new ArrayList<>();

        // 部装数据
        stopDurationInfoVos.addAll(stepRequiredMapper.getAssembleDurationInfo(lotNo));

        // 总装数据
        stopDurationInfoVos.addAll(stepRequiredMapper.getStopDurationInfo(lotNo));

        return stopDurationInfoVos;
    }


    /**
     * 计算两个时间点之间的间隔时间并返回
     *
     * @param first  第一条记录
     * @param second 第二条记录
     * @return 带间隔时间的列表
     */
    private List<StopDurationInfoVo> calculateDuration(StopDurationInfoVo first, StopDurationInfoVo second) {
        DateTime firstEndTime = first.getFirstEndTime();
        DateTime secondEndTime = second.getFirstEndTime();

        if (firstEndTime != null && secondEndTime != null) {
            Long durationMillis = secondEndTime.getTime() - firstEndTime.getTime();
            Duration duration = Duration.ofMillis(durationMillis);
            String durationStr = String.format("%d小时%d分钟",
                    duration.toHours(),
                    duration.toMinutes() % 60
            );

            System.out.println("第一条记录结束时间: " + firstEndTime);
            System.out.println("第二条记录结束时间: " + secondEndTime);
            System.out.println("时间间隔: " + durationStr);

            // 更新第一条记录的间隔时间字段
            first.setStopDurations(durationStr);

            // 创建结果列表并添加第一条记录
            List<StopDurationInfoVo> result = new ArrayList<>();
            result.add(first);

            return result;
        } else {
            System.out.println("时间戳为null，无法计算时间间隔。");
            return new ArrayList<>();
        }
    }
}
